package com.sh.data.engine.web.webapi.controller.integration;

import com.sh.data.engine.application.model.dto.base.PagerResponse;
import com.sh.data.engine.application.model.dto.dataasset.FieldInfoDTO;
import com.sh.data.engine.application.model.dto.dataasset.TableInfoBizDTO;
import com.sh.data.engine.application.model.dto.integration.DocumentCaptureDTO;
import com.sh.data.engine.application.model.dto.integration.PreviewDataDTO;
import com.sh.data.engine.application.model.dto.workspace.PortalSiteFileUploadDTO;
import com.sh.data.engine.application.model.request.integration.CreateSqlRequest;
import com.sh.data.engine.application.model.request.integration.DocumentCaptureCreateSqlRequest;
import com.sh.data.engine.application.model.request.integration.SaveTaskWithFromTextRequest;
import com.sh.data.engine.application.service.integration.DocumentCaptureApplicationService;
import com.sh.data.engine.common.constants.HttpStatus;
import com.sh.data.engine.common.constants.code.BizCodes;
import com.sh.data.engine.common.enumDefinition.ProjectStatisticTypeEnum;
import com.sh.data.engine.common.exception.BusinessException;
import com.sh.data.engine.common.util.ServletUtils;
import com.sh.data.engine.domain.annotation.LogExecution;
import com.sh.data.engine.domain.annotation.ProjectStatisticExecution;
import com.sh.data.engine.domain.annotation.userlog.Business;
import com.sh.data.engine.domain.annotation.userlog.EngineOperation;
import com.sh.data.engine.web.webapi.controller.base.response.RestResponseEntity;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.List;

/**
 * @author: mengzheng.mhc
 * @date: 2024/6/26 9:55
 */
@RequestMapping("/documentCapture")
@RestController
@Tag(name = "数据集成-文件采集", description = "文件采集相关API")
@Slf4j
public class DocumentCaptureController {

    @Autowired
    private DocumentCaptureApplicationService documentCaptureApplicationService;

    /**
     * @description : 解析上传的文件并展示（支持xlsx，xls，csv三种文件）
     * @author : tinglan.ys
     * @date : 2021/12/23
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 1, isAdd = 1)
    @PostMapping(value = "/fileParsing")
    @Operation(summary = "解析上传的文件并展示（支持xlsx，xls，csv三种文件）")
    @LogExecution(operation = EngineOperation.UPLOAD, business = Business.文件采集)
//    @Log(
//        business = Business.文件采集,
//        operation = Operation.UPLOAD)
    public RestResponseEntity<List<List<String>>> fileParsing(HttpServletRequest request, @RequestPart("file") MultipartFile file) {
        if (file.isEmpty() || file.getSize() == 0) {
            throw new BusinessException(BizCodes.REQUEST_PARAMETER_ERROR, HttpStatus.BAD_REQUEST);
        }

        List<List<String>> rows = documentCaptureApplicationService.parseFile(file, request.getParameterMap());
        return new RestResponseEntity<>(rows);
    }

    /**
     * @description : 上传要同步的文件，返回文件路径
     * @author : tinglan.ys
     * @date : 2022/3/17
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/upload")
    @Operation(summary = "上传要同步的文件，返回文件路径")
    @LogExecution(operation = EngineOperation.UPLOAD, business = Business.文件采集)
    public RestResponseEntity<PortalSiteFileUploadDTO> uploadFile(@RequestPart("file") MultipartFile file) {
        if (file.isEmpty() || file.getSize() == 0) {
            throw new BusinessException(BizCodes.REQUEST_PARAMETER_ERROR, HttpStatus.BAD_REQUEST);
        }

        var result = documentCaptureApplicationService.uploadFile(file);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 分页查询文件采集列表，查询条件是目标表
     * @author : tinglan.ys
     * @date : 2022/3/14
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getCaptureList")
    @Operation(summary = "分页查询文件采集列表，查询条件是目标表")
    public RestResponseEntity<PagerResponse<DocumentCaptureDTO>> getCaptureList(
        @RequestParam(required = false) String tableName,
        @RequestParam(required = false, defaultValue = "1") Integer pageNum,
        @RequestParam(required = false, defaultValue = "10") Integer pageSize) {

        Long projectId = ServletUtils.getProjectId();

        var result = documentCaptureApplicationService.getCaptureList(tableName, pageNum, pageSize, projectId);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 选择目标表（查询该空间下的表列表）
     * @author : tinglan.ys
     * @date : 2022/3/11
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getTableList")
    @Operation(summary = "选择目标表（查询该空间下的表列表）")
    public RestResponseEntity<List<TableInfoBizDTO>> getTables() {
        Long projectId = ServletUtils.getProjectId();

        var result = documentCaptureApplicationService.getTableList(projectId);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 获取该表的字段
     * @author : tinglan.ys
     * @date : 2022/3/11
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getTableField")
    @Operation(summary = "选择目标表（查询该空间下的表列表）")
    public RestResponseEntity<List<FieldInfoDTO>> getTableField(@RequestParam String tblName) {
        Long projectId = ServletUtils.getProjectId();

        var result = documentCaptureApplicationService.getTableField(projectId, tblName);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 文件同步任务导入
     * @author : tinglan.ys
     * @date : 2022/3/11
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 1, isAdd = 1)
    @PostMapping(value = "/saveTaskWithFromText")
    @Operation(summary = "文件同步任务导入")
    @LogExecution(operation = EngineOperation.IMPORT, business = Business.文件采集)
//    @Log(
//        business = Business.文件采集,
//        operation = Operation.IMPORT)
    public RestResponseEntity<Boolean> saveTaskWithFromText(
        @Valid @RequestBody SaveTaskWithFromTextRequest saveTaskWithFromTextRequest) {
        var result = documentCaptureApplicationService.saveTaskWithFromText(saveTaskWithFromTextRequest);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 获取运行日志 id为业务id
     * @author : tinglan.ys
     * @date : 2022/3/18
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getLog")
    @Operation(summary = "获取运行日志")
    public RestResponseEntity<List<String>> getLog(@RequestParam Long id) {
        var result = documentCaptureApplicationService.getLog(id);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 删除记录
     * @author : tinglan.ys
     * @date : 2022/3/21
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/del")
    @Operation(summary = "删除记录")
    @LogExecution(operation = EngineOperation.DEL, business = Business.文件采集)
//    @Log(
//        business = Business.文件采集,
//        operation = Operation.DEL)
    public RestResponseEntity<Boolean> del(@RequestParam Long id) {
        var result = documentCaptureApplicationService.del(id);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 查看数据
     * @author : tinglan.ys
     * @date : 2022/3/21
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getData")
    @Operation(summary = "查看数据(前10条)")
    public RestResponseEntity<PreviewDataDTO> getData(
        @RequestParam @NotBlank(message = "表名不能为空") String targetTblName) {
        var result = documentCaptureApplicationService.getData(targetTblName);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 一键建表
     * @author : tinglan.ys
     * @date : 2022/3/24
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/createTable")
    @Operation(summary = "一键建表")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.TABLE)
    @LogExecution(operation = EngineOperation.ADD, business = Business.文件采集)
//    @Log(
//        business = Business.文件采集,
//        operation = Operation.DATA_SYNC_CREATE_TABLE)
    public RestResponseEntity<TableInfoBizDTO> createTable(
        @RequestBody @Valid CreateSqlRequest createSqlRequest) {
        var result = documentCaptureApplicationService.createTable(createSqlRequest);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 一键建表sql
     * @author : tinglan.ys
     * @date : 2022/3/24
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/createSql")
    @Operation(summary = "一键建表sql")
    public RestResponseEntity<String> createSql(
        @Parameter(description = "列数", required = true) @RequestParam Integer colNum) {
        var result = documentCaptureApplicationService.createSql(colNum);
        return RestResponseEntity.success(result);
    }

    /**
     * 一键建表sql(自动转换表名、列名)
     *
     * @param request 文件采集一键建表请求
     * @return sql
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WJCJ, readWriteStatus = 0)
    @PostMapping("/createSqlAutoParse")
//    @Log(
//        business = Business.文件采集,
//        operation = Operation.DATA_SYNC_CREATE_TABLE)
    @Operation(summary = "一键建表sql(自动转换表名、列名)")
    @LogExecution(operation = EngineOperation.DATA_SYNC_CREATE_TABLE, business = Business.文件采集)
    public RestResponseEntity<String> createSqlAutoParse(
        @RequestBody DocumentCaptureCreateSqlRequest request) {
        var result = documentCaptureApplicationService.createSqlAutoParse(request);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 下载文件
     * @param id 文件id
     * @return 文件
     */
    @Operation(summary = "导出文件", description = "导出文件")
    @GetMapping("/exportFile")
    @LogExecution(operation = EngineOperation.EXPORT, business = Business.文件采集)
    public void exportFile(@RequestParam Long id,
                           HttpServletResponse response) {
       documentCaptureApplicationService.exportFile(id, response);
       response.setStatus(HttpServletResponse.SC_OK);
    }

}
